package com.acme.bankapp.service.bank;

import java.io.*;
import java.net.Socket;

/**
 * Created by alex on 8/24/14.
 */
public class BankClient implements  Runnable{
    BufferedReader isReader=null;
    BufferedWriter osWriter=null;
    private String host;
    private int port;

    public BankClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    /**
     * Main method to start  <code>BankClient</code> from console.
     * @param  args  The <code>host</code> and  <code>port</code> to be connected.
     *
     */
    public static void main(String[] args) {
        if (args.length != 2) {
            System.err.println("Not enough arguments: start BankClient with arguments: host port");
            return;
        }
        BankClient client = new BankClient(args[0], Integer.parseInt(args[1]));
        client.run();
    }

    /**
     * Starts a new Bank thin client and connects to the Bank server
     * Sends commands from  isReader (or Console if <code>isReader</code> is null) throw socket to the Bank server.
     * Receives responses from the same socket and Print them to osWriter (or Console of osWriter is null)
     *
     * <p> Every line is one command. Every command should be send to the server.  Available commands:
     *  exit
     *      - close the client. Note: before closing, client sends "exit" message to the server
     *  add account_type=s;balance=10.0;overdraft=0;name=Alex;gender=m
     *      - adds new client to the bank. Example is shown
     *  delete Alex
     *      - deletes client with name=Alex (Business rules tell that name is unique identification for client)

     */
    @Override
    public void run() {
        String message=null;
        String command=null;
        String response=null;
        try (Socket socket = new Socket(host, port);
             BufferedWriter writerToSocket = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
             BufferedReader readerFromSocket = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        ) {


            if (isReader==null){
                isReader= new BufferedReader(new InputStreamReader(System.in));
            }
            if (osWriter==null){
                osWriter= new BufferedWriter(new OutputStreamWriter(System.out));
            }
            response = readerFromSocket.readLine();
            osWriter.write(response);
            osWriter.newLine();
            osWriter.flush();

            outer:while(true) {
                message = isReader.readLine().trim();
                command = message.substring(0,message.indexOf(' ')>0?message.indexOf(' '):message.length());
                switch (command){
                    case "exit":
                        writerToSocket.write(message);
                        writerToSocket.newLine();
                        writerToSocket.flush();
                        return; //TODO check if "break outer" works;
                    case "add":
                    case "delete":
                        writerToSocket.write(message);
                        writerToSocket.newLine();
                        writerToSocket.flush();

                        response = readerFromSocket.readLine();
                        osWriter.write(response);
                        osWriter.newLine();
                        osWriter.flush();
                        break;
                    default:
                        osWriter.write("Bad command: try again.");
                        osWriter.newLine();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try{
                if (isReader!=null) isReader.close();
                if (osWriter!=null) osWriter.close();
            }
            catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}
